home *** CD-ROM | disk | FTP | other *** search
/ Mac Magazin/MacEasy 21 / Mac Magazin and MacEasy Magazine CD - Issue 21.iso / Wissenschaft & Technik / yorick12vr1-nofpu folder / include / prefix.i < prev    next >
Text File  |  1995-07-26  |  5KB  |  155 lines

  1. /*
  2.    PREFIX.I
  3.    Functions to read and write arrays of real numbers tagged by
  4.    a prefix at the beginning of each line.
  5.  
  6.    $Id$
  7.  */
  8. /*    Copyright (c) 1994.  The Regents of the University of California.
  9.                     All rights reserved.  */
  10.  
  11. func prefix_find(f, prefix, delimit=)
  12. /* DOCUMENT prefix_find(f, prefix)
  13.      scan to the first line of text file F which begins with the
  14.      blank delimited prefix PREFIX.  (You may specify other delimiters
  15.      by giving prefix_find a DELIMIT keyword, whose value will be
  16.      passed to the strtok function.)  The return value is 1 if such
  17.      a line was found, 0 if not.  In the first case, F will be positioned
  18.      to reread the prefixed line; in the second case, F will be at the
  19.      end-of-file.
  20.  
  21.    SEE ALSO: prefix_read, prefix_write, strtok
  22.  */
  23. {
  24.   if (is_void(delimit)) delimit= " \t\n";
  25.   found= 0;
  26.   while (line= rdline(f)) {
  27.     if (strtok(line,delimit)(1)==prefix) {
  28.       found= 1;
  29.       backup, f;
  30.       break;
  31.     }
  32.   }
  33.   return found;
  34. }
  35.  
  36. func prefix_read(f, prefix, delimit=, comment=)
  37. /* DOCUMENT value_array= prefix_read(f, prefix)
  38.      reads lines of text file F which begin with the blank delimited
  39.      prefix PREFIX.  (You may specify other delimiters by giving
  40.      prefix_read a DELIMIT keyword, whose value will be passed to the
  41.      strtok function.)  Stops when a line not beginning with that
  42.      prefix is encountered.  You may also supply a COMMENT keyword,
  43.      which should be a function accepting a string argument and
  44.      returning 0 to indicate that the line is not a comment line,
  45.      and 1 to indicate that it is a comment.  By default, blank lines
  46.      and lines beginning with "#" are taken as comments and skipped.
  47.  
  48.      The returned VALUE_ARRAY is [] if no PREFIX lines were found,
  49.      and an array of type double and length equal to the total number
  50.      of numbers Ni:
  51.  
  52.        prefix N1 N2 N3 N4
  53.        prefix N5 N6
  54.        prefix ... Nn
  55.  
  56.    SEE ALSO: prefix_find, prefix_write, prefix_comment, strtok
  57.  */
  58. {
  59.   if (is_void(delimit)) delimit= " \t\n";
  60.   if (is_void(comment)) comment= prefix_comment;
  61.   n= l= 0;
  62.   values= array(pointer, 100);
  63.   target= array(0.0, 256);   /* max number of values per line */
  64.   while (line= rdline(f)) {
  65.     tok= strtok(line,delimit);
  66.     if (tok(1)==prefix) {
  67.       nn= sread(prefix_unD(tok(2)), target);
  68.       if (nn>0) {
  69.     n+= nn;
  70.     if (l==numberof(values)) grow, values, array(pointer, 100);
  71.     values(++l)= &target(1:nn);
  72.       }
  73.     } else if (!comment(line)) {
  74.       backup, f;
  75.       break;
  76.     }
  77.   }
  78.   if (!n) return [];
  79.   result= array(0.0, n);
  80.   n= 0;
  81.   for (i=1 ; i<=l ; i++) {
  82.     target= *values(i);
  83.     nn= n+numberof(target);
  84.     result(n+1:nn)= target;
  85.     n= nn;
  86.   }
  87.   return result;
  88. }
  89.  
  90. func prefix_comment(line)
  91. /* DOCUMENT prefix_comment(line)
  92.      the default comment detector function for prefix_read, makes
  93.      blank lines and any line beginning with "#" as its first non-blank
  94.      character a comment.
  95.  */
  96. {
  97.   tok= strtok(line)(1);
  98.   return (strlen(tok)<1 || strpart(tok,1:1)=="#");
  99. }
  100.  
  101. func prefix_unD(text)
  102. {
  103.   if (text) {
  104.     c= *pointer(text);
  105.     d= where(c=='D' | c=='d');
  106.     if (numberof(d)) {
  107.       c(d)= 'e';
  108.       text= string(&c);
  109.     }
  110.   }
  111.   return text;
  112. }
  113.  
  114. func prefix_write(f, prefix, values, ndigits=, width=)
  115. /* DOCUMENT prefix_read, f, prefix, value_array
  116.      writes lines of text file F which begin with the prefix PREFIX:
  117.      
  118.        prefix N1 N2 N3 N4 N5
  119.        prefix N6 N7 N8 N9 N10
  120.        prefix N11 N12
  121.  
  122.      The format is %14.6e by default, but you can adjust the ".6" by
  123.      specifying an NDIGITS keyword (6 is the default).
  124.  
  125.      Yorick will put as many numbers as fit within 79 characters by
  126.      default, and each successive line begins with PREFIX.  You can
  127.      change this default line width by specifying a WIDTH keyword
  128.      (default 79).
  129.  
  130.    SEE ALSO: prefix_find, prefix_read
  131.  */
  132. {
  133.   if (is_void(width)) width= 79;
  134.   if (is_void(ndigits)) ndigits= 6;
  135.   else if (ndigits>24) ndigits= 24;
  136.   else if (ndigits<0) ndigits= 0;
  137.   ntot= 8+ndigits;
  138.   format= swrite(format="%%%ld.%lde",ntot,ndigits);
  139.   l= (width-strlen(prefix))/ntot;
  140.   if (l<1) l= 1;
  141.   n= numberof(values);
  142.   nlines= n/l;
  143.   j= n%l;
  144.   text= array(prefix, (j? nlines+1 : nlines));
  145.   for (i=1 ; i<=l ; i++) {
  146.     /* format the text one column at a time --
  147.        some columns may be one shorter than others */
  148.     if (i>n) break;
  149.     column= swrite(format=format, values(i:0:l));
  150.     if (j && i>j) text(1:nlines)+= column;
  151.     else text+= column;
  152.   }
  153.   write, f, format="%s\n", text;
  154. }
  155.